## 4.6. Setting Environment Variables

When a script is called it receives a lot of environment variables, as we have seen. It may be that you want to pass some of your own. There are two directives to do this: `SetEnv` and `PassEnv`.

### 4.6.1. SetEnv

>     SetEnv variable value
>     Server config, virtual hosts

This directive sets an environment variable that is then passed to CGI scripts. We can invent our own environment variables and give them values. For instance, we might have several virtual hosts on the same machine that use the same script. To distinguish which virtual host called the script (in a more abstract way than using the `HTTP_HOST` environment variable), we could make up our own environment variable `VHOST`:

>     <VirtualHost host1>
>     SetEnv VHOST customers
>     ...
>     </VirtualHost>
>     <VirtualHost host2>
>     SetEnv VHOST salesmen
>     ...
>     </VirtualHost>

### 4.6.2. UnsetEnv

>     UnsetEnv variable variable ...
>     Server config, virtual hosts

Takes a list of environment variables and removes them.

### 4.6.3. PassEnv

>     PassEnv

This directive passes an environment variable to CGI scripts from the environment that was in force when Apache was started.[41] The script might need to know the operating system, so you could use the following:

> [41]Note that when Apache is started during the system boot, the environment can be surprisingly sparse.

>     PassEnv OSTYPE

This variation assumes that your operating system sets `OSTYPE`, which is by no means a foregone conclusion.

### 4.6.4. Browsers

A real problem on the Web is that people are free to choose their own browsers and not all browsers work alike or even nearly alike. They vary enormously in their capabilities. Some browsers display images, others won't. Some that display images won't display frames, tables, or Java, and so on.

You can try to circumvent this problem by asking the customer to go to different parts of your script ("Click here to see the frames version"), but in real life people often do not know what their browser will and won't do. A lot of them will not even understand what question you are asking. To get around this problem, Apache can detect the browser type and set environment variables so that your CGI scripts can detect the type and act accordingly.

### 4.6.4.1. SetEnvIf and SetEnvIfNoCase

>     SetEnvIf attribute regex envar[=value] [..]
>     SetEnvIfNoCase attribute regex envar[=value] [..]

The attribute can be one of the HTTP request header fields, such as `Host`, `User-Agent`, `Referer`, and/or one of the following:

`Remote_Host`

  The client's hostname, if available

`Remote_Addr`

  The client's IP address

`Remote_User`

  The client's authenticated username, if available

`Request_Method`

  `GET`, `POST`, etc.

`Request_URI`

  The part of the URL following the scheme and host

The `NoCase` version works the same except that regular expression matching is evaluated without regard to letter case.

### 4.6.4.2. BrowserMatch and BrowserMatchNoCase

>     BrowserMatch regex env1[=value1] env2[=value2] ...

>     BrowserMatchNoCase regex env1[=value1] env2[=value2] ...

regex is a regular expression matched against the client's `User-Agent` header, and env1, env2, ... are environment variables to be set if the regular expression matches. The environment variables are set to value1, value2, etc., if present.

So, for instance, we might say:

>     BrowserMatch ^Mozilla/[23] tables=3 java

The symbol ^ means start from the beginning of the header and match the string `Mozilla/` followed by either a 2 or 3. If this is successful, then Apache creates, and, if required, specifies values for, the given list of environment variables. These variables are invented by the author of the script, and in this case are:

>     tables=3
>     java

In this CGI script, the client can test these variables and take the appropriate action.

`BrowserMatchNoCase` is simply a case-blind version of `BrowserMatch`. That is, it doesn't care whether letters are upper- or lowercase. `mOZILLA` works as well as `MoZiLlA`.

Note that there is no difference between `BrowserMatch` and `SetEnvIf` `User-Agent`. `BrowserMatch` exists for backward compatibility.

### 4.6.5. Internal Use of Environment Variables

Environment variables can also be used to control some aspects of the behavior of Apache. Note that because these are just environment variables, nothing checks that you have spelt them correctly, so be very careful when using them.

### 4.6.5.1. nokeepalive

This disables `KeepAlive` (see Chapter 3, "Toward a Real Web Site"). Some versions of Netscape claimed to support `KeepAlive`, but actually had a bug that meant the server appeared to hang (in fact, Netscape was attempting to reuse the existing connection, even though the server had closed it). The directive:

>     BrowserMatch "Mozilla/2" nokeepalive

disables `KeepAlive` for those buggy versions.[42]

> [42]And, incidentally, for early versions of Microsoft Internet Explorer, which unwisely pretended to be Netscape Navigator.

### 4.6.5.2. force-response-1.0

Forces Apache to respond with HTTP/1.0 to an HTTP/1.0 client, instead of with HTTP/1.1 as is called for by the HTTP/1.1 spec. This is required to work around certain buggy clients that don't recognize HTTP/1.1 responses. Various clients have this problem. The current recommended settings are as follows:

>     BrowserMatch "RealPlayer4\.0" force-response-1.0
>     BrowserMatch "Java/1\.0" force-response-1.0
>     BrowserMatch "JDK/1\.0" force-response-1.0

### 4.6.5.3. downgrade-1.0

Forces Apache to downgrade to HTTP/1.0 even though the client is HTTP/1.1 (or higher). Microsoft Internet Explorer 4.0b2 earned the dubious distinction of being the only known client to require all three of these settings:

>     BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0

Copyright © 2001 O'Reilly & Associates. All rights reserved.